package com.feeyin.radar.crm.service.impl;

import com.feeyin.radar.commons.DateUtils;
import com.feeyin.radar.commons.Page;
import com.feeyin.radar.commons.StringUtils;
import com.feeyin.radar.crm.dao.CustomerDAO;
import com.feeyin.radar.crm.dao.SaleRecordDAO;
import com.feeyin.radar.crm.form.SaleFunnelForm;
import com.feeyin.radar.crm.model.Customer;
import com.feeyin.radar.crm.service.SaleFunnelService;
import com.feeyin.radar.sys.dao.BusinessTargetDAO;
import com.feeyin.radar.sys.dao.DepartmentDAO;
import com.feeyin.radar.sys.dao.ManageSetDAO;
import com.feeyin.radar.sys.dao.SaleStageSetDAO;
import com.feeyin.radar.sys.dao.UserDAO;
import com.feeyin.radar.sys.model.SaleStageSet;
import com.feeyin.radar.sys.model.Users;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SaleFunnelServiceImpl
  implements SaleFunnelService
{
  private UserDAO userDAO;
  private DepartmentDAO departmentDAO;
  private SaleStageSetDAO saleStageSetDAO;
  private CustomerDAO customerDAO;
  private BusinessTargetDAO businessTargetDAO;
  private ManageSetDAO manageSetDAO;
  private SaleRecordDAO saleRecordDAO;

  public UserDAO getUserDAO()
  {
    return this.userDAO;
  }

  public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
  }

  public DepartmentDAO getDepartmentDAO() {
    return this.departmentDAO;
  }

  public void setDepartmentDAO(DepartmentDAO departmentDAO) {
    this.departmentDAO = departmentDAO;
  }

  public SaleStageSetDAO getSaleStageSetDAO() {
    return this.saleStageSetDAO;
  }

  public void setSaleStageSetDAO(SaleStageSetDAO saleStageSetDAO) {
    this.saleStageSetDAO = saleStageSetDAO;
  }

  public CustomerDAO getCustomerDAO() {
    return this.customerDAO;
  }

  public void setCustomerDAO(CustomerDAO customerDAO) {
    this.customerDAO = customerDAO;
  }

  public BusinessTargetDAO getBusinessTargetDAO() {
    return this.businessTargetDAO;
  }

  public void setBusinessTargetDAO(BusinessTargetDAO businessTargetDAO) {
    this.businessTargetDAO = businessTargetDAO;
  }

  public ManageSetDAO getManageSetDAO() {
    return this.manageSetDAO;
  }

  public void setManageSetDAO(ManageSetDAO manageSetDAO) {
    this.manageSetDAO = manageSetDAO;
  }

  public SaleRecordDAO getSaleRecordDAO() {
    return this.saleRecordDAO;
  }

  public void setSaleRecordDAO(SaleRecordDAO saleRecordDAO) {
    this.saleRecordDAO = saleRecordDAO;
  }

  public List getDeptSalePersons(Integer userId) {
    if (userId == null) return null;
    Users user = new Users();
    user = this.userDAO.getUser(userId);
    if (user == null) return null;
    String deptIds = this.departmentDAO.getCurrentDeptIdAndSubDeptIdsByDeptId(user.getDeptId());
    if (StringUtils.isEmpty(deptIds)) return null;
    user = new Users();
    user.setDeptIds(deptIds);
    user.setIsActivity("1");
    user.setIsAdmin(Integer.valueOf(1));
    return this.userDAO.getUsersByDynamic(user);
  }

  public List getSaleFunnel(Integer currentUserId, SaleFunnelForm saleFunnelForm)
  {
    List list = new ArrayList();
    if (currentUserId == null) return list;
    if (saleFunnelForm == null) return list;
    if (StringUtils.isEmpty(saleFunnelForm.getFunnelTarget())) return list;
    if (StringUtils.isEmpty(saleFunnelForm.getTime())) return list;
    if (saleFunnelForm.getSalePersonId() == null) return list;

    if ("1".equals(saleFunnelForm.getFunnelTarget()))
      list = getSaleFunnelByCustomerNum(currentUserId, saleFunnelForm);
    else if ("2".equals(saleFunnelForm.getFunnelTarget())) {
      list = getSaleFunnelByPredictCost(currentUserId, saleFunnelForm);
    }
    return list;
  }

  public List getPageFunnelCustomers(Integer saleStageId, Integer currentUserId, SaleFunnelForm saleFunnelForm, Page page)
  {
    List customers = new ArrayList();
    if (saleStageId == null) return null;
    if (currentUserId == null) return null;
    if (saleFunnelForm == null) return null;
    if (page == null) return null;

    Customer customer = new Customer();
    if (saleFunnelForm.getSalePersonId().compareTo(Integer.valueOf(0)) == 0) {
      Users user = new Users();
      user = this.userDAO.getUser(currentUserId);
      if (user == null) return null;
      Integer deptId = user.getDeptId();
      String deptIds = "";
      if (deptId != null) {
        deptIds = this.departmentDAO.getCurrentDeptIdAndSubDeptIdsByDeptId(deptId);
      }
      if (StringUtils.isEmpty(deptIds)) return null;

      customer.setDeptIdsEx(deptIds);
    }
    else {
      customer.setSalePersonId(saleFunnelForm.getSalePersonId());
    }

    Date startDate = DateUtils.getCurrentSeasonFirstDay();
    Date endDate = DateUtils.getCurrentSeasonEndDay();

    if ("1".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentSeasonFirstDay();
      endDate = DateUtils.getCurrentSeasonEndDay();
    } else if ("2".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentYearFirstDay();
      endDate = DateUtils.getCurrentYearEndDay();
    }

    customer.setStartPredictContractDate(startDate);
    customer.setEndPredictContractDate(endDate);
    customer.setSaleStageId(saleStageId);

    customer.setCustomerCategory("1");
    customer.setIsSaleStage("1");
    customer.setSaleStatus("0");
    customers = this.customerDAO.getPageCustomersByDynamic(customer, page);

    if ((customers == null) || (customers.size() <= 0)) return null;
    for (int i = 0; i < customers.size(); i++) {
      Customer cCustomer = new Customer();
      cCustomer = (Customer)customers.get(i);

      cCustomer.setLinkNum(this.saleRecordDAO.getSaleRecordCountByCustomerId(cCustomer.getId()));

      cCustomer.setLastLink(this.saleRecordDAO.getSaleRecordLastLinkByCustomerId(cCustomer.getId()));
    }
    return customers;
  }

  public Integer getPageFunnelCustomersCount(Integer saleStageId, Integer currentUserId, SaleFunnelForm saleFunnelForm)
  {
    List customers = new ArrayList();
    if (saleStageId == null) return Integer.valueOf(0);
    if (currentUserId == null) return Integer.valueOf(0);
    if (saleFunnelForm == null) return Integer.valueOf(0);

    Customer customer = new Customer();
    if (saleFunnelForm.getSalePersonId().compareTo(Integer.valueOf(0)) == 0) {
      Users user = new Users();
      user = this.userDAO.getUser(currentUserId);
      if (user == null) return Integer.valueOf(0);
      Integer deptId = user.getDeptId();
      String deptIds = "";
      if (deptId != null) {
        deptIds = this.departmentDAO.getCurrentDeptIdAndSubDeptIdsByDeptId(deptId);
      }
      if (StringUtils.isEmpty(deptIds)) return Integer.valueOf(0);

      customer.setDeptIdsEx(deptIds);
    }
    else {
      customer.setSalePersonId(saleFunnelForm.getSalePersonId());
    }

    Date startDate = DateUtils.getCurrentSeasonFirstDay();
    Date endDate = DateUtils.getCurrentSeasonEndDay();

    if ("1".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentSeasonFirstDay();
      endDate = DateUtils.getCurrentSeasonEndDay();
    } else if ("2".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentYearFirstDay();
      endDate = DateUtils.getCurrentYearEndDay();
    }

    customer.setStartPredictContractDate(startDate);
    customer.setEndPredictContractDate(endDate);
    customer.setSaleStageId(saleStageId);

    customer.setCustomerCategory("1");
    customer.setIsSaleStage("1");
    customer.setSaleStatus("0");
    return this.customerDAO.getPageCustomersCountByDynamic(customer);
  }

  private List getSaleFunnelByCustomerNum(Integer currentUserId, SaleFunnelForm saleFunnelForm)
  {
    BigDecimal avgSingle = this.manageSetDAO.getAvgSingle();

    BigDecimal target = new BigDecimal(0);

    List saleStages = new ArrayList();
    saleStages = this.saleStageSetDAO.getSaleStages();
    if ((saleStages == null) || (saleStages.size() <= 0)) return null;

    List customers = new ArrayList();
    Customer customer = new Customer();
    if (saleFunnelForm.getSalePersonId().compareTo(Integer.valueOf(0)) == 0) {
      Users user = new Users();
      user = this.userDAO.getUser(currentUserId);
      if (user == null) return null;
      Integer deptId = user.getDeptId();
      String deptIds = "";
      if (deptId != null) {
        deptIds = this.departmentDAO.getCurrentDeptIdAndSubDeptIdsByDeptId(deptId);
      }
      if (StringUtils.isEmpty(deptIds)) return null;

      customer.setDeptIds2(deptIds);

      if ("1".equals(saleFunnelForm.getTime()))
        target = this.businessTargetDAO.getSeasonTargetByDeptIds(deptIds);
      else if ("2".equals(saleFunnelForm.getTime()))
        target = this.businessTargetDAO.getYearTargetByDeptIds(deptIds);
    }
    else
    {
      customer.setSalePersonId(saleFunnelForm.getSalePersonId());

      if ("1".equals(saleFunnelForm.getTime()))
      {
        target = this.businessTargetDAO.getSeasonTargetBySalePersonId(saleFunnelForm.getSalePersonId());
      } else if ("2".equals(saleFunnelForm.getTime()))
      {
        target = this.businessTargetDAO.getYearTargetBySalePersonId(saleFunnelForm.getSalePersonId());
      }
    }

    Date startDate = DateUtils.getCurrentSeasonFirstDay();
    Date endDate = DateUtils.getCurrentSeasonEndDay();
    if ("1".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentSeasonFirstDay();
      endDate = DateUtils.getCurrentSeasonEndDay();
    } else if ("2".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentYearFirstDay();
      endDate = DateUtils.getCurrentYearEndDay();
    }

    customer.setStartPredictContractDate(startDate);
    customer.setEndPredictContractDate(endDate);
    customer.setCustomerCategory("1");

    customer.setIsSaleStage("1");
    customer.setSaleStatus("0");

    customers = this.customerDAO.getCustomersByDynamic(customer);
    if ((customers == null) || (customers.size() <= 0)) return null;
    for (int i = 0; i < saleStages.size(); i++) {
      int tempNum = 0;
      SaleStageSet saleStageSet = new SaleStageSet();
      saleStageSet = (SaleStageSet)saleStages.get(i);
      String stageId = saleStageSet.getStageCode();
      BigDecimal successRate = saleStageSet.getSuccessRate();

      int stageCustomerNum = getStageCustomerNum(target, avgSingle, successRate);

      for (int j = 0; j < customers.size(); j++) {
        customer = new Customer();
        customer = (Customer)customers.get(j);

        if ((customer.getSaleStageId() == null) || 
          (!stageId.equals(customer.getSaleStageId().toString())))
          continue;
        tempNum++;
      }

      if ((stageCustomerNum > 0) && (tempNum > 0)) {
        BigDecimal temp = new BigDecimal(tempNum).divide(new BigDecimal(stageCustomerNum), 10, 4);
        saleStageSet.setSuccessRate(temp.multiply(new BigDecimal(100)));
      } else {
        saleStageSet.setSuccessRate(new BigDecimal(0));
      }
    }
    return saleStages;
  }

  private List getSaleFunnelByPredictCost(Integer currentUserId, SaleFunnelForm saleFunnelForm)
  {
    BigDecimal target = new BigDecimal(0);

    List saleStages = new ArrayList();
    saleStages = this.saleStageSetDAO.getSaleStages();
    if ((saleStages == null) || (saleStages.size() <= 0)) return null;

    List customers = new ArrayList();
    Customer customer = new Customer();
    if (saleFunnelForm.getSalePersonId().compareTo(Integer.valueOf(0)) == 0) {
      Users user = new Users();
      user = this.userDAO.getUser(currentUserId);
      if (user == null) return null;
      Integer deptId = user.getDeptId();
      String deptIds = "";
      if (deptId != null) {
        deptIds = this.departmentDAO.getCurrentDeptIdAndSubDeptIdsByDeptId(deptId);
      }
      if (StringUtils.isEmpty(deptIds)) return null;

      customer.setDeptIds2(deptIds);

      if ("1".equals(saleFunnelForm.getTime()))
        target = this.businessTargetDAO.getSeasonTargetByDeptIds(deptIds);
      else if ("2".equals(saleFunnelForm.getTime()))
        target = this.businessTargetDAO.getYearTargetByDeptIds(deptIds);
    }
    else
    {
      customer.setSalePersonId(saleFunnelForm.getSalePersonId());

      if ("1".equals(saleFunnelForm.getTime()))
      {
        target = this.businessTargetDAO.getSeasonTargetBySalePersonId(saleFunnelForm.getSalePersonId());
      } else if ("2".equals(saleFunnelForm.getTime()))
      {
        target = this.businessTargetDAO.getYearTargetBySalePersonId(saleFunnelForm.getSalePersonId());
      }
    }

    Date startDate = DateUtils.getCurrentSeasonFirstDay();
    Date endDate = DateUtils.getCurrentSeasonEndDay();

    if ("1".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentSeasonFirstDay();
      endDate = DateUtils.getCurrentSeasonEndDay();
    } else if ("2".equals(saleFunnelForm.getTime())) {
      startDate = DateUtils.getCurrentYearFirstDay();
      endDate = DateUtils.getCurrentYearEndDay();
    }

    customer.setStartPredictContractDate(startDate);
    customer.setEndPredictContractDate(endDate);

    customer.setCustomerCategory("1");
    customer.setIsSaleStage("1");
    customer.setSaleStatus("0");
    customers = this.customerDAO.getCustomersByDynamic(customer);
    if ((customers == null) || (customers.size() <= 0)) return null;

    for (int i = 0; i < saleStages.size(); i++) {
      BigDecimal tempCost = new BigDecimal(0);
      SaleStageSet saleStageSet = new SaleStageSet();
      saleStageSet = (SaleStageSet)saleStages.get(i);
      String stageId = saleStageSet.getStageCode();
      BigDecimal successRate = saleStageSet.getSuccessRate();

      BigDecimal stageCost = getStageCost(target, successRate);

      for (int j = 0; j < customers.size(); j++) {
        customer = new Customer();
        customer = (Customer)customers.get(j);

        if ((customer.getSaleStageId() == null) || 
          (!stageId.equals(customer.getSaleStageId().toString())))
          continue;
        if ((customer.getPredictCost() != null) && (customer.getPredictCost().compareTo(new BigDecimal(0)) > 0)) {
          tempCost = tempCost.add(customer.getPredictCost());
        }

      }

      if ((stageCost != null) && (stageCost.compareTo(new BigDecimal(0)) > 0) && 
        (tempCost != null) && (tempCost.compareTo(new BigDecimal(0)) > 0)) {
        BigDecimal temp = tempCost.divide(stageCost, 10, 4);
        saleStageSet.setSuccessRate(temp.multiply(new BigDecimal(100)));
      } else {
        saleStageSet.setSuccessRate(new BigDecimal(0));
      }
    }
    return saleStages;
  }

  private int getStageCustomerNum(BigDecimal target, BigDecimal avgSingle, BigDecimal successRate)
  {
    int customerNum = 0;
    if (target == null) return 0;
    if (target.compareTo(new BigDecimal(0)) <= 0) return 0;

    if (avgSingle == null) return 0;
    if (avgSingle.compareTo(new BigDecimal(0)) <= 0) return 0;

    if (successRate == null) return 0;
    if (successRate.compareTo(new BigDecimal(0)) <= 0) return 0;

    BigDecimal t1 = new BigDecimal(0);
    BigDecimal t2 = new BigDecimal(0);
    BigDecimal t3 = new BigDecimal(0);
    t1 = target.divide(avgSingle, 2, 4);
    if (t1.compareTo(new BigDecimal(0)) <= 0) return 0;
    t2 = t1.divide(successRate, 2, 4);
    if (t2.compareTo(new BigDecimal(0)) <= 0) return 0;
    t3 = t2.multiply(new BigDecimal(100));
    if ((t3.compareTo(new BigDecimal(0)) > 0) && (t3.compareTo(new BigDecimal(1)) < 0)) return 1;
    customerNum = t3.intValue();
    return customerNum;
  }

  private BigDecimal getStageCost(BigDecimal target, BigDecimal successRate)
  {
    BigDecimal stageCost = new BigDecimal(0);
    if (target == null) return stageCost;
    if (target.compareTo(new BigDecimal(0)) <= 0) return stageCost;

    if (successRate == null) return stageCost;
    if (successRate.compareTo(new BigDecimal(0)) <= 0) return stageCost;

    BigDecimal t1 = new BigDecimal(0);
    t1 = target.divide(successRate, 2, 4);
    if (t1.compareTo(new BigDecimal(0)) <= 0) return stageCost;
    stageCost = t1.multiply(new BigDecimal(100));
    return stageCost;
  }
}